﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraSplashScreen;
using WarehouseManagement.BusinessLogic.DTO;
using WarehouseManagement.Presenters.PO;
using WarehouseManagement.ViewModels.PO;
using WarehouseManagement.Views.Export;
using WarehouseManagement.Views.Shared;

namespace WarehouseManagement.Views.PO
{
    public partial class ViewSupplierDebt : XtraForm, IView<ViewSupplierDebtPresenter>, IViewSupplierDebtViewModel
    {
        private ViewSupplierDebtPresenter _presenter;

        public ViewSupplierDebt()
        {
            InitializeComponent();
            _presenter = SetupPresenter();
        }

        private void cboOption_SelectedIndexChanged(object sender, EventArgs e)
        {
            AssignDate();
        }

        private void AssignDate()
        {
            var today = DateTime.Now;
            switch (cboOption.SelectedIndex)
            {
                case 1:
                    {
                        DateTime startOfWeek = DateTime.Today.AddDays(-1 * (int)(DateTime.Today.DayOfWeek));
                        this.FromDate = startOfWeek;
                        this.ToDate = startOfWeek.AddDays(6);
                        break;
                    }
                case 0:
                    {
                        this.FromDate = today;
                        this.ToDate = FromDate;
                        break;
                    }
                case 2:
                    {
                        this.FromDate = new DateTime(today.Year, today.Month, 1);
                        this.ToDate = new DateTime(today.Year, today.Month, DateTime.DaysInMonth(today.Year, today.Month));
                        break;
                    }
                case 3:
                    {
                        var period = GetPeriod(today.Month);
                        this.FromDate = GetStartDayOfPeriod(period, today.Year);
                        var todate = this.FromDate.AddMonths(2);
                        this.ToDate = new DateTime(todate.Year, todate.Month, DateTime.DaysInMonth(todate.Year, todate.Month));
                        break;
                    }
                case 4:
                    {
                        this.FromDate = new DateTime(today.Year, 1, 1);
                        this.ToDate = new DateTime(today.Year, 12, DateTime.DaysInMonth(today.Year, 12));
                        break;
                    }

                case 5:
                    {
                        // Thang 1
                        this.FromDate = new DateTime(today.Year, 1, 1);
                        this.ToDate = new DateTime(today.Year, 1, DateTime.DaysInMonth(today.Year, 1));
                        break;
                    }
                case 6:
                    {
                        // Thang 1
                        this.FromDate = new DateTime(today.Year, 2, 1);
                        this.ToDate = new DateTime(today.Year, 2, DateTime.DaysInMonth(today.Year, 2));
                        break;
                    }
                case 7:
                    {
                        // Thang 1
                        this.FromDate = new DateTime(today.Year, 3, 1);
                        this.ToDate = new DateTime(today.Year, 3, DateTime.DaysInMonth(today.Year, 3));
                        break;
                    }
                case 8:
                    {
                        // Thang 1
                        this.FromDate = new DateTime(today.Year, 4, 1);
                        this.ToDate = new DateTime(today.Year, 4, DateTime.DaysInMonth(today.Year, 4));
                        break;
                    }
                case 9:
                    {
                        // Thang 1
                        this.FromDate = new DateTime(today.Year, 5, 1);
                        this.ToDate = new DateTime(today.Year, 5, DateTime.DaysInMonth(today.Year, 5));
                        break;
                    }
                case 10:
                    {
                        // Thang 1
                        this.FromDate = new DateTime(today.Year, 6, 1);
                        this.ToDate = new DateTime(today.Year, 6, DateTime.DaysInMonth(today.Year, 6));
                        break;
                    }
                case 11:
                    {
                        // Thang 1
                        this.FromDate = new DateTime(today.Year, 7, 1);
                        this.ToDate = new DateTime(today.Year, 7, DateTime.DaysInMonth(today.Year, 7));
                        break;
                    }
                case 12:
                    {
                        // Thang 1
                        this.FromDate = new DateTime(today.Year, 8, 1);
                        this.ToDate = new DateTime(today.Year, 8, DateTime.DaysInMonth(today.Year, 8));
                        break;
                    }
                case 13:
                    {
                        // Thang 1
                        this.FromDate = new DateTime(today.Year, 9, 1);
                        this.ToDate = new DateTime(today.Year, 9, DateTime.DaysInMonth(today.Year, 9));
                        break;
                    }
                case 14:
                    {
                        // Thang 1
                        this.FromDate = new DateTime(today.Year, 10, 1);
                        this.ToDate = new DateTime(today.Year, 10, DateTime.DaysInMonth(today.Year, 10));
                        break;
                    }
                case 15:
                    {
                        // Thang 11
                        this.FromDate = new DateTime(today.Year, 11, 1);
                        this.ToDate = new DateTime(today.Year, 11, DateTime.DaysInMonth(today.Year, 11));
                        break;
                    }
                case 16:
                    {
                        // Thang 12
                        this.FromDate = new DateTime(today.Year, 12, 1);
                        this.ToDate = new DateTime(today.Year, 12, DateTime.DaysInMonth(today.Year, 12));
                        break;
                    }

                case 17:
                    {
                        // Quy 1
                        this.FromDate = GetStartDayOfPeriod(1, today.Year);
                        var todate = FromDate.AddMonths(2);
                        this.ToDate = new DateTime(todate.Year, todate.Month, DateTime.DaysInMonth(todate.Year, todate.Month));
                        break;
                    }
                case 18:
                    {
                        // Quy 2
                        this.FromDate = GetStartDayOfPeriod(2, today.Year);
                        var todate = FromDate.AddMonths(2);
                        this.ToDate = new DateTime(todate.Year, todate.Month, DateTime.DaysInMonth(todate.Year, todate.Month));
                        break;
                    }
                case 19:
                    {
                        // Quy 3
                        this.FromDate = GetStartDayOfPeriod(3, today.Year);
                        var todate = FromDate.AddMonths(2);
                        this.ToDate = new DateTime(todate.Year, todate.Month, DateTime.DaysInMonth(todate.Year, todate.Month));
                        break;
                    }
                case 20:
                    {
                        // Quy 4
                        this.FromDate = GetStartDayOfPeriod(4, today.Year);
                        var todate = FromDate.AddMonths(2);
                        this.ToDate = new DateTime(todate.Year, todate.Month, DateTime.DaysInMonth(todate.Year, todate.Month));
                        break;
                    }
            }
        }

        private int GetPeriod(int month)
        {
            if (month >= 1 && month <= 3)
                return 1;
            else if (month >= 4 && month <= 6)
                return 2;
            else if (month >= 7 && month <= 9)
                return 3;
            else
                return 4;
        }

        private DateTime GetStartDayOfPeriod(int period, int year)
        {
            if (period < 1 || period > 4)
                throw new ArgumentException("Period invalid");
            return new DateTime(year, (period * 3) - 2, 1);
        }

        public DateTime FromDate
        {
            get
            {
                return txtFromDate.DateTime;
            }
            set
            {
                txtFromDate.DateTime = value;
            }
        }

        public DateTime ToDate
        {
            get
            {
                return txtToDate.DateTime;
            }
            set
            {
                txtToDate.DateTime = value;
            }
        }

        private void txtFromDate_EditValueChanged(object sender, EventArgs e)
        {
            if (FromDate > ToDate)
                ToDate = FromDate;
        }

        private void txtToDate_EditValueChanged(object sender, EventArgs e)
        {
            if (ToDate < FromDate)
                FromDate = ToDate;
        }

        private void ViewSupplierDebt_Load(object sender, EventArgs e)
        {
            cboOption_SelectedIndexChanged(sender, e);
            TestMasterDetail();
        }

        private void TestMasterDetail()
        {

            gridControl1.DataSource = new NestedRecords();
        }


        public ViewSupplierDebtPresenter SetupPresenter()
        {
            var p = new ViewSupplierDebtPresenter();
            p.RegisterViewModel(this);
            return p;
        }

        private void simpleButton1_Click(object sender, EventArgs e)
        {
            var grv = gridControl1.MainView as GridView;
            var obj = grv.GetSelectedRows().First();
            var obj2 = grv.GetFocusedRow();
        }




        public IEnumerable<MerchandiseDebitDTO> DebitItems
        {
            get
            {
                return grdDebt.DataSource as IEnumerable<MerchandiseDebitDTO>;
            }
            set
            {
                grdDebt.DataSource = value;
            }
        }

        private void btnView_Click(object sender, EventArgs e)
        {
            SplashScreenManager.ShowForm(typeof(WaitForm1));
            _presenter.LoadSupplierDebtViewData();
            SplashScreenManager.CloseForm();
        }

        private void grvDebt_MasterRowExpanded(object sender, CustomMasterRowEventArgs e)
        {
            var masterGrv = sender as GridView;
            GridView childGrv = masterGrv.GetDetailView(e.RowHandle, e.RelationIndex) as GridView;
            childGrv.BeginUpdate();
            int colIndex = 0;

            childGrv.Columns[colIndex].Caption = "Tên mặt hàng";
            childGrv.Columns[colIndex].OptionsColumn.AllowEdit = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowFocus = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowShowHide = false;
            colIndex++;

            childGrv.Columns[colIndex].Caption = "ĐVT";
            childGrv.Columns[colIndex].OptionsColumn.AllowEdit = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowFocus = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowShowHide = false;
            colIndex++;

            childGrv.Columns[colIndex].Caption = "Số lượng";
            childGrv.Columns[colIndex].OptionsColumn.AllowEdit = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowFocus = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowShowHide = false;
            childGrv.Columns[colIndex].DisplayFormat.Assign(new DevExpress.Utils.FormatInfo() { FormatType = DevExpress.Utils.FormatType.Numeric, FormatString = "n" });
            colIndex++;

            childGrv.Columns[colIndex].Caption = "Đơn giá";
            childGrv.Columns[colIndex].OptionsColumn.AllowEdit = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowFocus = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowShowHide = false;
            childGrv.Columns[colIndex].DisplayFormat.Assign(new DevExpress.Utils.FormatInfo() { FormatType = DevExpress.Utils.FormatType.Numeric, FormatString = "n" });
            colIndex++;

            childGrv.Columns[colIndex].Caption = "Thuế (%)";
            childGrv.Columns[colIndex].OptionsColumn.AllowEdit = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowFocus = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowShowHide = false;
            childGrv.Columns[colIndex].DisplayFormat.Assign(new DevExpress.Utils.FormatInfo() { FormatType = DevExpress.Utils.FormatType.Numeric, FormatString = "n" });
            colIndex++;

            childGrv.Columns[colIndex].Caption = "Phí Ship";
            childGrv.Columns[colIndex].OptionsColumn.AllowEdit = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowFocus = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowShowHide = false;
            childGrv.Columns[colIndex].DisplayFormat.Assign(new DevExpress.Utils.FormatInfo() { FormatType = DevExpress.Utils.FormatType.Numeric, FormatString = "n" });
            colIndex++;

            childGrv.Columns[colIndex].Caption = "Đơn giá (Sau thuế + Ship)";
            childGrv.Columns[colIndex].OptionsColumn.AllowEdit = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowFocus = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowShowHide = false;
            childGrv.Columns[colIndex].DisplayFormat.Assign(new DevExpress.Utils.FormatInfo() { FormatType = DevExpress.Utils.FormatType.Numeric, FormatString = "n" });
            colIndex++;

            childGrv.Columns[colIndex].Caption = "Thành tiền";
            childGrv.Columns[colIndex].OptionsColumn.AllowEdit = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowFocus = false;
            childGrv.Columns[colIndex].OptionsColumn.AllowShowHide = false;
            childGrv.Columns[colIndex].DisplayFormat.Assign(new DevExpress.Utils.FormatInfo() { FormatType = DevExpress.Utils.FormatType.Numeric, FormatString = "n" });
            colIndex++;
            childGrv.EndUpdate();
        }

        private void btnCreateReceipts_Click(object sender, EventArgs e)
        {
            Receipt receipt = new Receipt();
            var obj = GetFocusedObject();
            receipt.PartnerId = obj.PartnerId;
            receipt.PartnerName = obj.PartnerName;
            receipt.DocumentNumber = obj.DocumentNumber;
            receipt.DocumentDate = obj.Date;
            receipt.ReceiptDate = DateTime.Now;
            receipt.Debt = obj.Debt;

            var paid = _presenter.GetTotalReceiveMoneyOf(obj.DocumentNumber, obj.Date.Date, DateTime.Now.Date, obj.Date);
            receipt.RemainDebt = obj.Debt - paid;
            receipt.Paid = receipt.RemainDebt;
            if (!obj.IsPO)
            {
                var val =  _presenter.GetDebitUntilDate(obj.PartnerId, DateTime.Now);
                receipt.DocumentDate = val;
                var debt = _presenter.GetDebitUntilToday(obj.PartnerId);
                receipt.Debt = debt;
            }


            receipt.OnReceiptCreated = new Receipt.ReceiptCreatedHandler(ReceiptCreated);
            receipt.ShowDialog();
        }

        private void ReceiptCreated(bool success)
        {
            if (success)
                _presenter.LoadSupplierDebtViewData();
        }

        private void gridControl1_Click(object sender, EventArgs e)
        {

        }

        private void dropDownButton1_Click(object sender, EventArgs e)
        {

        }

        private void grvDebt_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            var obj = GetFocusedObject();
            HandleImportButtons(obj);

        }

        private void HandleImportButtons(MerchandiseDebitDTO obj)
        {
            if (obj == null)
            {
                btnCreateReceipts.Enabled = dropBtnImport.Enabled = false;
            }
            else
            {
                btnCreateReceipts.Enabled = dropBtnImport.Enabled = true;
                btnImportFromPO.Enabled = obj.IsPO;
            }
        }
        private MerchandiseDebitDTO GetFocusedObject()
        {
            var obj = grvDebt.GetFocusedRow() as MerchandiseDebitDTO;
            return obj;
        }

        private void dropBtnImport_Click(object sender, EventArgs e)
        {
            ImportAsNormal();
        }

        private void ImportAsNormal()
        {
            var mainForm = this.ParentForm as MainForm;
            if (mainForm == null) return;
            if ((MainForm.FrmImportNew != null)
                || (MainForm.FrmImportNew != null && !MainForm.FrmImportNew.IsDisposed))
            {
                MainForm.FrmImportNew.Close();
            }
            var row = GetFocusedObject();
            if (row != null)
            {
                MainForm.FrmImportNew = new NewEditImport(NewEditImport.EditMode.New);
                MainForm.FrmImportNew.MdiParent = mainForm;
                MainForm.FrmImportNew.SupplierId = row.PartnerId;
                MainForm.FrmImportNew.ImportForDocumentNumber = row.DocumentNumber;
                MainForm.FrmImportNew.UsedCurrencyId = row.CurrencyId;
                MainForm.FrmImportNew.ExchangeRate = row.ExchangeRate;
                MainForm.FrmImportNew.EnableSupplierSelection(false);
                MainForm.FrmImportNew.Show();
            }
        }

        private void ImportFromSelectedPO()
        {
            ImportAsNormal();
            MainForm.FrmImportNew.EnableCurrencySelection(false);
            MainForm.FrmImportNew.LoadImportListFromPO();
        }

        private void btnImportFromPO_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            ImportFromSelectedPO();
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
    public class NestedRecord
    {
        private string fName;
        ArrayList fChildList = null;

        public NestedRecord(string name, ArrayList childList)
        {
            this.fName = name;
            this.fChildList = childList;
        }

        public string Name
        {
            get { return fName; }
            set { fName = value; }
        }

        public ArrayList ChildList
        {
            get { return fChildList; }
            set { fChildList = value; }
        }
    }

    public class NestedRecords : ArrayList
    {
        public NestedRecords()
        {
            Add(new NestedRecord("Customers", CreateChildCustomerRecords()));
            Add(new NestedRecord("Products", CreateChildCustomerRecords()));
            Add(new NestedRecord("Shippers", CreateChildCustomerRecords()));
        }
        public virtual new NestedRecord this[int index]
        {
            get { return (NestedRecord)(base[index]); }
        }

        private ArrayList CreateChildCustomerRecords()
        {
            var c = new ArrayList();
            var r = new Random();
            for (var i = 0; i < 10; i++)
                c.Add(new { Id = r.Next(), Name = "Customer " + r.Next().ToString() });
            return c;
        }
    }

}
